<?php

/**
 * 框架入口文件
 *
 * 框架资源初始化并实现MVC模式调度
 *
 * @author Lan <lanyg.com@gmail.com>
 * @link http://www.lanyg.com/projects/lanp
 * @copyright Copyright &copy; 2011-2012 Yanguang Lan (www.lanyg.com)
 * @license LGPL (http://www.gnu.org/licenses/lgpl.html)
 * @version $Id$
 */

/* 定义框架版本 */

if ( !defined('VERSION') )
    define('VERSION', '1.0');

/* 定义路径分隔符别名 */

if ( !defined('DS') )
    define('DS', DIRECTORY_SEPARATOR);

/* 定义应用程序目录路径 */

if( !defined('APPDIR') )
    define('APPDIR', BASEDIR . 'appfiles' . DS);

/* 定义spl_autoload 包含路径 */

set_include_path(get_include_path()
    . PATH_SEPARATOR . BASEDIR . 'systemfiles' . DS . 'plugins' . DS
    . PATH_SEPARATOR . BASEDIR . 'sharefiles' . DS . 'models' . DS
    . PATH_SEPARATOR . BASEDIR . 'sharefiles' . DS . 'plugins' . DS
    . PATH_SEPARATOR . APPDIR . 'models' . DS
    . PATH_SEPARATOR . APPDIR . 'plugins' . DS
);

/* spl_autoload 定制 */

spl_autoload_extensions('.php,.inc');

$spl_funs = spl_autoload_functions();
if ( false === $spl_funs )
    spl_autoload_register();
elseif ( !in_array('spl_autoload', $spl_funs) )
    spl_autoload_register('spl_autoload');

/* mvc 类 */

/**
 * mvc 实现类
 *
 * @package Lanp
 * @author Lan
 */

class MVC
{
    /**
     * 事件实例对象
     */
     public $event = null;

    /**
     * 配置信息数组变量
     *
     * @var array $cofing
     * @access pulic
     */

    public $config = array();

    /**
     * 控制器实例对象
     *
     * @var object $controller
     * @access public
     */

    public $controller = null;

    /**
     * 控制器名称
     *
     * @access public
     * @var string $controllerName
     */

    public $controllerName = '';

    /**
     * 动作方法
     *
     * @var string $action
     * @access public
     */

    public $action = '';

    /**
     * 动作方法名称
     *
     * @access public
     * @var string $actionName
     */

    public $actionName = '';


    /**
     * 获取 PATH INFO 值
     *
     * @var string $pathInfo
     * @access private
     */

    private $pathInfo = '';

    /**
     * 针对 PATH INFO 的路径分段数组变量
     *
     * @var array $urlSegments
     * @access public
     */

    public $urlSegments = array();

    /**
     * 构造函数
     *
     * @access pulic
     */

    public function  __construct($id = 'default')
    {
        //获取单列
        self::instance($this, $id);
        
    }

    /**
     * MVC 主方法
     *
     * @access public
     */

    public function main()
    {
        //main 方法执行计时开始
        self::timer('app_start_time');

        //程序异常、错误事件绑定
        $this->setupErrorHandling();

        //载入配置文件内容
        include_once APPDIR . 'configs' . DS . 'application.php';
        $this->config = $config;

        //载入事件监听
        $this->event = new MVC_Event();
        include_once APPDIR . 'configs' . DS . 'event.php';
        
        //会话设置
        $this->event->callEventHandler('EVENT_SESSION', array($this->config['session']));
        
        //设置魔术过滤
        ini_set('magic_quotes_runtime', 0);

        //启动会话
        session_start();

        //定义常量
        define('PHP_SELF', htmlspecialchars(!empty ($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']));
        define('HTTP_REFERER', (!empty ($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : FALSE));
        define('IS_GET', (!empty ($_SERVER['REQUEST_METHOD']) ? (strtolower($_SERVER['REQUEST_METHOD']) == 'get') : FALSE));
        define('IS_POST', (!empty ($_SERVER['REQUEST_METHOD']) ? (strtolower($_SERVER['REQUEST_METHOD']) == 'post') : FALSE));
        define('IS_AJAX', (!empty ($_SERVER['HTTP_X_REQUESTED_WITH']) ? (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') : FALSE));
        define('NOW', time());

        //设置pathInfo
        $this->pathInfo = !empty($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';

        //路由解析
        $this->setupRouting();

        //获取url路径分段
        $this->setupSegments();

        //去除GPC魔术过滤
        if ( function_exists(get_magic_quotes_gpc()) && get_magic_quotes_gpc() ) {
            $_GET = stripslashes_deep($_GET);
            $_POST = stripslashes_deep($_POST);
            $_COOKIE = stripslashes_deep($_COOKIE);
        }

        //转发控制器
        $this->setupController();

        //获取执行动作
        $this->setupAction();

	//建立控制器对象实例
	$controller_class = $this->controllerName . '_Controller';
        $this->controller = new $controller_class(true);
		
        //自动载入类
        $this->setupAutoloads();


        //执行控制器动作
        $this->controller->{$this->action}();

        //统计输出执行时间
        if ( $this->config['timer'] ) {
            self::timer('app_end_time');
            echo 'Timer:' . self::timer('app_start_time', 'app_end_time');
        }
    }

    /**
     * 程序错误事件绑定
     *
     * @access public
     */

    public function setupErrorHandling()
    {
        if ( defined('ERROR_HANDLING') && ERROR_HANDLING == 1 ) {
            set_exception_handler(array('Error_ExceptionHandler', 'handleException'));
            require_once BASEDIR . 'systemfiles' . DS . 'plugins' . DS . 'error_errorhandler.php';
            set_error_handler('Error_ErrorHandler');
        }else{
            set_exception_handler(array('Error_ExceptionHandler', 'noHandleException'));
        }
    }

    /**
     * 路由解析
     *
     * @access public
     */

    public function setupRouting()
    {
          if ( !empty ($this->config['route']) && !empty ($this->config['routing']['search']) && !empty ($this->config['routing']['replace']) )
              $this->pathInfo = preg_replace(
              $this->config['routing']['search'],
              $this->config['routing']['replace'],
              $this->pathInfo);
    }

    /**
     * 获取url路径分段
     *
     * @access public
     */

    public function setupSegments()
    {
        if ( !empty ($this->pathInfo) )
            $this->urlSegments = explode('/', $this->pathInfo);
        if ( !empty ($this->urlSegments[3]) )
            for ( $i = 3; $i<count($this->urlSegments); $i = $i+2)
                $_GET[$this->urlSegments[$i]] = $this->urlSegments[$i+1];
    }

    /**
     * 转发控制器
     *
     * @access public
     */

    public function setupController()
    {
        if ( !empty ($this->config['root_controller']) ) {
            $this->controllerName = $this->config['root_controller'];
            $controller_file = APPDIR . 'controllers' . DS . strtolower($this->controllerName) . '.php';
        } else {
            $this->controllerName = !empty ($this->urlSegments[1]) ? $this->urlSegments[1] :
                               (!empty ($_GET['c']) ? $_GET['c'] :
                               $this->config['default_controller']);
            $controller_file = APPDIR . 'controllers' . DS . strtolower($this->controllerName) . '.php';
            if ( !file_exists($controller_file) )
                throw new Exception('Missing Controller');
        }

        include $controller_file;
    }

    /**
     * 获取执行动作
     *
     * @access public
     */

    public function setupAction()
    {
        if ( !empty ($this->config['root_action']) ) {
            $this->actionName = $this->config['root_action'];
        } else {
            $this->actionName = !empty ($this->urlSegments[2]) ? $this->urlSegments[2] :
                            (!empty ($_GET['a']) ? $_GET['a'] : $this->config['default_action']);
        }
        $this->action = $this->actionName . 'Action';
    }

    /**
     * 自动载入类
     *
     * @access public
     */

    public function setupAutoloads()
    {
        include APPDIR . 'configs' . DS . 'autoload.php';
        if ( !empty ($config['libraries']) ) {
            foreach ( $config['libraries'] as $library )
                if ( !is_array($library) )
                    $this->controller->load->library($library[0], $library[1]);
                else
                    $this->controller->load->library($library);
        }

        if ( !empty ($config['scripts']) ) {
            foreach ( $config['scripts'] as $script )
                $this->controller->load->script($script);
        }
    }

    /**
     * 获取某个对象单例
     *
     * @access public static
     */

    public static function &instance($new_instance = null, $id = 'default')
    {
        static $instance = array();
        if ( isset ($new_instance) && is_object($new_instance) )
            $instance[$id] = $new_instance;
        return  $instance[$id];
    }

    /**
     * timer计时器
     *
     * @access public static
     */

    public static function timer($id = null, $id2 = null)
    {
        static $times = array();
        if ( $id != null && $id2 != null )
            return  (isset ($times[$id]) && isset ($times[$id2])) ? ($times[$id2] - $times[$id]) : false;
        elseif ( $id != null )
            return $times[$id] = microtime(true);
        else
            return false;
    }
}

    /**
     * get_magic_quotes_gpc 过滤器
     *
     * @param value mix
     */

    function stripslashes_deep($value)
    {
        $value = is_array($value) ? array_map('stripslashes_deep', $value) :
                                    stripslashes($value);
        return $value;
    }
?>